package com.castle.fortress.admin.cms.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.castle.fortress.admin.cms.dto.CmsColConfigDto;
import com.castle.fortress.admin.cms.entity.CmsColConfigEntity;
import com.castle.fortress.admin.cms.entity.CmsModelEntity;
import com.castle.fortress.admin.cms.mapper.CmsColConfigMapper;
import com.castle.fortress.admin.cms.service.CmsColConfigService;
import com.castle.fortress.common.entity.RespBody;
import com.castle.fortress.common.enums.YesNoEnum;
import com.castle.fortress.common.exception.BizException;
import com.castle.fortress.common.respcode.BizErrorCode;
import com.castle.fortress.common.utils.ConvertUtil;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * cms模型字段配置表 服务实现类
 *
 * @author castle
 * @since 2022-03-03
 */
@Service
public class CmsColConfigServiceImpl extends ServiceImpl<CmsColConfigMapper, CmsColConfigEntity> implements CmsColConfigService {
    /**
    * 获取查询条件
    * @param cmsColConfigDto
    * @return
    */
    public QueryWrapper<CmsColConfigEntity> getWrapper(CmsColConfigDto cmsColConfigDto){
        QueryWrapper<CmsColConfigEntity> wrapper= new QueryWrapper();
        if(cmsColConfigDto != null){
            CmsColConfigEntity cmsColConfigEntity = ConvertUtil.transformObj(cmsColConfigDto,CmsColConfigEntity.class);
            wrapper.like(cmsColConfigEntity.getModelId() != null,"model_id",cmsColConfigEntity.getModelId());
            wrapper.like(StrUtil.isNotEmpty(cmsColConfigEntity.getColTitle()),"col_title",cmsColConfigEntity.getColTitle());
            wrapper.like(StrUtil.isNotEmpty(cmsColConfigEntity.getColName()),"col_name",cmsColConfigEntity.getColName());
            wrapper.like(StrUtil.isNotEmpty(cmsColConfigEntity.getPropName()),"prop_name",cmsColConfigEntity.getPropName());
            wrapper.like(cmsColConfigEntity.getLimitSize() != null,"limit_size",cmsColConfigEntity.getLimitSize());
        }
        return wrapper;
    }


    @Override
    public IPage<CmsColConfigDto> pageCmsColConfig(Page<CmsColConfigDto> page, CmsColConfigDto cmsColConfigDto) {
        QueryWrapper<CmsColConfigEntity> wrapper = getWrapper(cmsColConfigDto);
        Page<CmsColConfigEntity> pageEntity = new Page(page.getCurrent(), page.getSize());
        Page<CmsColConfigEntity> cmsColConfigPage=baseMapper.selectPage(pageEntity,wrapper);
        Page<CmsColConfigDto> pageDto = new Page(cmsColConfigPage.getCurrent(), cmsColConfigPage.getSize(),cmsColConfigPage.getTotal());
        pageDto.setRecords(ConvertUtil.transformObjList(cmsColConfigPage.getRecords(),CmsColConfigDto.class));
        return pageDto;
    }


    @Override
    public List<CmsColConfigDto> listCmsColConfig(CmsColConfigDto cmsColConfigDto){
        QueryWrapper<CmsColConfigEntity> wrapper = getWrapper(cmsColConfigDto);
        List<CmsColConfigEntity> list = baseMapper.selectList(wrapper);
        List<CmsColConfigDto> dtos= ConvertUtil.transformObjList(list,CmsColConfigDto.class);
        dtos.forEach(dto->{
            dto.setIsSys(false);
        });
        return dtos;
    }

    @Override
    public List<CmsColConfigEntity> fillType(Long modelId,List<CmsColConfigEntity> list) {
        for(CmsColConfigEntity e:list){
            if(modelId!=null){
                e.setModelId(modelId);
            }
            e.setId(IdWorker.getId());
            switch(e.getFormType()){
                //多行文本
                case 2:
                //复选框
                case 6: {
                    e.setColType("text");
                    break;
                }
                //日期
                case 7:
                    e.setColType("date");
                    break;
                //日期时间
                case 8:
                    e.setColType("datetime");
                    break;
                //富文本
                case 3:  e.setColType("longtext");
                    break;
                //开关
                case 12:
                //计数器
                case 13:
                    e.setColType("int");
                    break;
                //图片上传组件
                case 9:
                //文件上传组件
                case 10:{
                    if(e.getLimitSize() == 1){
                        e.setColType("varchar(255)");
                        break;
                    }else{
                        e.setColType("text");
                        break;
                    }
                }
                //单行文本  下拉框 单选框 视频上传组件
                default:
                    e.setColType("varchar(255)");
                    break;
            }
        }
        return list;
    }
    @Async
    @Override
    public void saveCols(CmsModelEntity cmsModelEntity, List<CmsColConfigEntity> entities) {
        if(entities!=null && !entities.isEmpty()){
            if(YesNoEnum.YES.getCode().equals(cmsModelEntity.getIsExtend())){
                entities = fillType(cmsModelEntity.getId(),entities);
                saveBatch(entities);
                //创建表
                List<String> tableNames=allTableNames();
                for(String name:tableNames){
                    if(name.equals("cms_model_"+cmsModelEntity.getCode())){
                        throw new BizException(BizErrorCode.FORM_TABLE_EXIST_ERROR);
                    }
                }
                baseMapper.createTable(cmsModelEntity.getCode(),entities);
            }
        }
    }
    @Async
    @Override
    public void updateCols(CmsModelEntity cmsModelEntity,List<CmsColConfigEntity> entities) {
        QueryWrapper<CmsColConfigEntity> w = new QueryWrapper<>();
        w.eq("model_id",cmsModelEntity.getId());
        //获取旧的字段信息
        List<CmsColConfigEntity> oldCols = baseMapper.selectList(w);
        //清除原数据  保存新数据
        baseMapper.delete(w);
        entities = fillType(cmsModelEntity.getId(),entities);
        saveBatch(entities);
        if(YesNoEnum.YES.getCode().equals(cmsModelEntity.getIsExtend())){
            if(entities!=null && !entities.isEmpty()){

                //新扩展字段
                if(oldCols == null || oldCols.isEmpty()){
                    saveCols(cmsModelEntity,entities);
                    //修改字段
                }else{
                    //修改表结构
                    List<CmsColConfigEntity> addCols=new ArrayList<>();
                    List<CmsColConfigEntity> modifyCols=new ArrayList<>();
                    List<CmsColConfigEntity> existCols=new ArrayList<>();
                    boolean isFind = false;
                    for(CmsColConfigEntity newCol:entities){
                        isFind=false;
                        for(CmsColConfigEntity oldCol:oldCols){
                            if(newCol.getColName().equals(oldCol.getColName())){
                                isFind=true;
                                existCols.add(oldCol);
                                if(!newCol.equals(oldCol)){
                                    modifyCols.add(newCol);
                                }
                                break;
                            }
                        }
                        if(!isFind){
                            addCols.add(newCol);
                        }
                    }
                    oldCols.removeAll(existCols);
                    //删除字段
                    if(!oldCols.isEmpty()){
                        baseMapper.alterTableDrop(cmsModelEntity.getCode(),oldCols);
                    }
                    //修改字段
                    if(!modifyCols.isEmpty()){
                        baseMapper.alterTableModify(cmsModelEntity.getCode(),modifyCols);
                    }
                    //添加字段
                    if(!addCols.isEmpty()){
                        baseMapper.alterTableAdd(cmsModelEntity.getCode(),addCols);
                    }
                }
                //扩展字段清空
            }else{
                if(oldCols!=null && !oldCols.isEmpty()){
                    baseMapper.dropTable(cmsModelEntity.getCode());
                }
            }
        }
    }

    @Override
    public List<String> allTableNames() {
        return baseMapper.allTableNames();
    }
    @Async
    @Override
    public void delCols(CmsModelEntity e) {
        QueryWrapper<CmsColConfigEntity> w = new QueryWrapper<>();
        w.eq("model_id",e.getId());
        //清除原数据  保存新数据
        baseMapper.delete(w);
        baseMapper.dropTable(e.getCode());

    }

    @Override
    public RespBody checkColumnRepeat(CmsColConfigDto dto) {
        //校验code
        QueryWrapper<CmsColConfigEntity> queryWrapper=new QueryWrapper();
        queryWrapper.eq("col_name",dto.getColName());
        List<CmsColConfigEntity> list = baseMapper.selectList(queryWrapper);
        if(list != null && !list.isEmpty()){
            //新增
            if(dto.getId() == null){
                return RespBody.fail(BizErrorCode.CMS_COL_REPEAT_ERROR);
                //修改
            }else{
                for(CmsColConfigEntity entity:list){
                    if(!entity.getId().equals(dto.getId())){
                        return RespBody.fail(BizErrorCode.CMS_COL_REPEAT_ERROR);
                    }
                }
            }
        }
        queryWrapper=new QueryWrapper();
        queryWrapper.eq("prop_name",dto.getPropName());
        list = baseMapper.selectList(queryWrapper);
        if(list != null && !list.isEmpty()){
            //新增
            if(dto.getId() == null){
                return RespBody.fail(BizErrorCode.CMS_PROP_REPEAT_ERROR);
                //修改
            }else{
                for(CmsColConfigEntity entity:list){
                    if(!entity.getId().equals(dto.getId())){
                        return RespBody.fail(BizErrorCode.CMS_PROP_REPEAT_ERROR);
                    }
                }
            }
        }
        return RespBody.data("校验通过");
    }

    @Override
    public List<CmsColConfigDto> listByChannel(Long channelId) {
        return ConvertUtil.transformObjList(baseMapper.listByChannel(channelId),CmsColConfigDto.class);
    }
}

